package com.jrx.anytxn.transaction.mq;

import com.alibaba.fastjson.JSONObject;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.BeanUtils;
import com.jrx.anytxn.common.uitl.JsonUtils;
import com.jrx.anytxn.feign.common.GateWayPredicate;
import com.jrx.anytxn.feign.gateway.response.SmsResponse02;
import com.jrx.anytxn.feign.gateway.service.IInnerGatewayService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrCodeTable;
import com.jrx.anytxn.param.entity.PrSmsTemplateTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrCodeTableMapper;
import com.jrx.anytxn.param.service.sms.ISmsTemplatesService;
import com.jrx.anytxn.transaction.bean.TemplateWrapper;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlSmsLog;
import com.jrx.anytxn.transaction.mapper.base.TlSmsLogMapper;
import com.jrx.anytxn.transaction.service.IDealGatewayService;
import com.jrx.anytxn.transaction.service.ISmsService;
import com.jrx.anytxn.transaction.utils.SmsTemplateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RocketMQMessageListener(
        topic = TransBizConstant.MQ_SMS_TOPIC + "${spring.cloud.nacos.discovery.metadata.currentVersion}",
        consumerGroup = TransBizConstant.MQ_SMS_GROUP + "${spring.cloud.nacos.discovery.metadata.currentVersion}",
        consumeThreadMax = 10
)
public class SmsMqConsumerService implements RocketMQListener<String> {

    private static final Logger logger = LoggerFactory.getLogger(SmsMqConsumerService.class);

    @Autowired
    private ISmsTemplatesService iSmsTemplatesService;
    @Autowired
    private ISmsService iSmsService;
    @Autowired
    private IDealGatewayService dealGatewayService;
    @Lazy
    @Autowired
    private IInnerGatewayService innerGatewayService;
    @Resource
    private TlSmsLogMapper tlSmsLogMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ExtPrCodeTableMapper extPrCodeTableMapper;


    @Override
    public void onMessage(String jSonMessage) {
        logger.info("MQ消费端获取到短信请求 ：{}", jSonMessage);
        TlSmsLog tlSmsLog;
        try {
            tlSmsLog = JsonUtils.json2pojo(jSonMessage, TlSmsLog.class);
        } catch (Exception e) {
            logger.error("MQ消费端JSon转换异常 ：{}", e);
            return;
        }
        try {
            String mobile = tlSmsLog.getMobile();
            String smsFilters = stringRedisTemplate.opsForValue().get(Constant.SMS_FILTER);
            if (StringUtils.isNotBlank(smsFilters)) {
                String[] smsFilter = smsFilters.split(",");
                if (Arrays.stream(smsFilter).anyMatch(num -> num.equalsIgnoreCase(mobile))) {
                    return;
                }
            } else {
                List<PrCodeTable> prCodeTables = extPrCodeTableMapper.selectAllByTypeIdAndTenId(Constant.SMS_FILTER, tlSmsLog.getTenantId());
                List<String> list = prCodeTables.stream().filter(code -> Constant.YES_FLAG.equalsIgnoreCase(code.getIsvalid())).map(PrCodeTable::getCodeId).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(list)) {
                    stringRedisTemplate.opsForValue().set(Constant.SMS_FILTER, String.join(",", list));
                    if (list.stream().anyMatch(num -> num.equalsIgnoreCase(mobile))) {
                        return;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("判断短信过滤异常", e);
        }
        //判断发送类型
        if (TransBizConstant.SEND_TYPE_0.equals(tlSmsLog.getSendType())) {
            try {
                sendSms(tlSmsLog);
            } catch (TxnBizException e) {
                logger.error("发送短信异常", e);
            }
        } else if (TransBizConstant.SEND_TYPE_1.equals(tlSmsLog.getSendType())) {
            try {
                iSmsService.sendWeChat(tlSmsLog);
            } catch (Exception e) {
                logger.error("发送微信信息异常", e);
            }
        } else {
            try {
                sendSms(tlSmsLog);
                iSmsService.sendWeChat(tlSmsLog);
            } catch (Exception e) {
                logger.error("发送信息异常", e);
            }

        }
    }

    /**
     * 发送短信消息
     *
     * @param tlSmsLog
     * @throws TxnBizException
     */
    private void sendSms(TlSmsLog tlSmsLog) throws TxnBizException {
        //1 根据短信模板ID获取短信模板内容
        PrSmsTemplateTable templateTable = iSmsTemplatesService.selectByTenantIdAndTemplateId(tlSmsLog.getTenantId(), tlSmsLog.getTemplateId());
        if (null == templateTable) {
            logger.error("SMS MQ消费端未获取到对应模板，模板编号 ：{},租户 ：{}", tlSmsLog.getTemplateId(), tlSmsLog.getTenantId());
            return;
        }

        //2 组装短信模板要素类
        TemplateWrapper templateWrapper = iSmsService.generateTemplateWrapper(tlSmsLog);

        //3 组装短信内容
        Map<String, Object> templateMap = BeanUtils.toMap(templateWrapper);
        logger.info("短信模板要素：{}", templateMap);
        String result = SmsTemplateUtils.templateProcess(templateTable.getTemplateContent(), templateMap);
        logger.info("加工后短信模板：{}", result);
        tlSmsLog.setSmsContent(result);

        SmsResponse02 response = null;
        //4 调用网关
        try {
            //组装请求参数
            String smsRequest02Json = dealGatewayService.buildSMSRequest(tlSmsLog, result);
            GateWayPredicate<SmsResponse02> smsPre = () -> innerGatewayService.sms(smsRequest02Json);
            response = smsPre.getRes(smsPre);
        } catch (Exception e) {
            logger.error("短信调用网关异常", e);
        }
        if (response == null) {
            tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_FAIL);
        } else {
            tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_SUC);
        }
        try {
            //更新短信流水
            tlSmsLogMapper.insertSelective(tlSmsLog);
            logger.info("MQ消费端短信流水处理完成,流水号：{}", tlSmsLog.getSeqNo());
        } catch (Exception e) {
            logger.error("短信插入数据库异常", e);
            logger.error("短信数据：{}", JSONObject.toJSONString(tlSmsLog));

        }

    }

}
